#pragma once

#include <QPushButton>
#include <QWidget>
#include <QIcon>
#include <QPoint>
#include <QTimer>
#include <QWindow>
#include <QMouseEvent>
#include <QPropertyAnimation>

class DockingTabWell;

/**
 * DockTab - 高级拖拽标签按钮
 * 基于QPushButton，支持复杂的拖拽交互和预览窗口
 */
class DockTab : public QPushButton
{
    Q_OBJECT
    
public:
    enum class TabType
    {
        MainTab,        // 主标签：不可关闭、不可拖出（可在任意位置）
        NormalTab,      // 普通标签：可关闭、可拖出
        DocumentTab,    // 文档标签
        ToolTab         // 工具标签
    };
    
    enum class DragState
    {
        None,           // 无拖拽
        Clicked,        // 刚点击，准备拖拽
        HorizontalDrag, // 横排拖拽（标签内重排序）
        PullOutDrag     // 拖出拖拽（创建新窗口）
    };
    
public:
    explicit DockTab(const QString& title, QWidget* parent = nullptr);
    explicit DockTab(const QIcon& icon, const QString& title, QWidget* parent = nullptr);
    ~DockTab();
    
    // === 基础属性 ===
    QString tabTitle() const { return Title; }
    void setTabTitle(const QString& title);
    
    QIcon tabIcon() const { return Icon; }
    void setTabIcon(const QIcon& icon);
    
    TabType tabType() const { return TabTypeValue; }
    void setTabType(TabType type);
    
    // === 状态管理 ===
    bool isActiveTab() const { return IsActive; }
    void setActiveTab(bool active);
    
    bool isClosable() const { return TabTypeValue != TabType::MainTab; }
    bool isDraggable() const { return TabTypeValue != TabType::MainTab; }
    bool canPullOut() const { return TabTypeValue != TabType::MainTab; }
    
    // === 内容管理 ===
    QWidget* contentWidget() const { return ContentWidget; }
    void setContentWidget(QWidget* widget);
    
    // === 拖拽相关 ===
    DragState currentDragState() const { return DragStateValue; }
    bool isDragging() const { return DragStateValue != DragState::None; }
    
    // === 位置管理（脱离Layout约束） ===
    QPoint originalPosition() const { return OriginalPosition; }
    void setOriginalPosition(const QPoint& pos);
    
    QPoint currentFloatingPosition() const { return FloatingPosition; }
    void setFloatingPosition(const QPoint& pos);
    
    // === 吸附预览 ===
    int previewDropIndex() const { return PreviewDropIndex; }
    void setPreviewDropIndex(int index);
    bool hasValidDropPreview() const { return PreviewDropIndex >= 0; }

public slots:
    // === 线性动画系统 ===
    void updateLinearAnimation();
    void onAnimationFinished();

signals:
    // 基础事件
    void tabActivated();
    void tabCloseRequested();
    
    // 拖拽事件
    void dragStarted(DragState dragType);
    void dragPositionChanged(const QPoint& globalPos);
    void dragFinished(DragState dragType, bool accepted);
    
    // 横排拖拽特定事件
    void horizontalDragPreview(int fromIndex, int toIndex);
    void horizontalDragCommit(int fromIndex, int toIndex);
    
    // 拖出拖拽特定事件
    void pullOutDragStarted(const QPoint& grabOffset);
    void pullOutPreviewMoved(const QPoint& globalPos);
    void pullOutWindowRequested(const QPoint& globalPos, QWidget* content);
    void returnToTabWell();

protected:
    // === Qt事件重写 ===
    void mousePressEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;
    void paintEvent(QPaintEvent* event) override;
    void enterEvent(QEnterEvent* event) override;
    void leaveEvent(QEvent* event) override;
    
    // === 自定义绘制 ===
    void paintTabBackground(QPainter& painter);
    void paintTabContent(QPainter& painter);
    void paintCloseButton(QPainter& painter);
    void paintDragPreview(QPainter& painter);

private:
    // === 核心拖拽逻辑 ===
    void startDragOperation(const QPoint& startPos);
    void updateDragOperation(const QPoint& currentPos);
    void finishDragOperation(const QPoint& endPos);
    
    // === 拖拽类型判断 ===
    DragState determineDragType(const QPoint& startPos, const QPoint& currentPos);
    bool shouldStartHorizontalDrag(const QPoint& delta);
    bool shouldStartPullOutDrag(const QPoint& delta);
    
    // === 横排拖拽逻辑 ===
    void processHorizontalDrag(const QPoint& currentPos);
    void processCardSwapLogic(int currentX); // 卡牌式位移调换逻辑
    void performCardSwap(int fromIndex, int toIndex); // 执行标签交换
    int calculateDropIndex(const QPoint& position);
    void showHorizontalDragPreview(int targetIndex);
    void commitHorizontalDrag();
    void revertHorizontalDrag();
    
    // === 拖出拖拽逻辑 ===
    void processPullOutDrag(const QPoint& currentPos);
    void createPreviewWindow(const QPoint& globalPos);
    void updatePreviewWindow(const QPoint& globalPos);
    void destroyPreviewWindow();
    void createRealWindow(const QPoint& globalPos);
    bool isMouseInTabWellArea(const QPoint& globalPos);
    QPixmap captureContentSnapshot(); // 捕获内容截图
    QPixmap captureIndependentWindowSnapshot(); // 捕获独立窗口快照（标签+内容）
    void drawTabButtonInSnapshot(QPainter& painter, const QRect& tabRect); // 在快照中绘制标签按钮
    void calculateMousePositionInSnapshot(const QPoint& globalPos); // 计算鼠标在快照中的精确位置
    
    // === 线性动画计算 ===
    void startLinearAnimation(const QPoint& fromPos, const QPoint& toPos, int durationMs = 200);
    void stopLinearAnimation();
    QPoint calculateLinearPosition(float progress);
    
    // === 工具函数 ===
    void setupTab();
    QRect closeButtonRect() const;
    bool isPointInCloseButton(const QPoint& pos) const;
    void updateTabAppearance();
    DockingTabWell* parentTabWell() const;
    QString calculateEllipsisText(const QString& originalText, int availableWidth, const QFont& font);

private:
    // === 基础属性 ===
    QString Title;
    QIcon Icon;
    TabType TabTypeValue;
    bool IsActive;
    QWidget* ContentWidget;
    
    // === 外观状态 ===
    bool IsHovered;
    bool IsCloseButtonHovered;
    bool ShowCloseButton;
    
    // === 拖拽状态机 ===
    DragState DragStateValue;
    bool JustClicked;             // 刚刚点击，等待拖拽开始
    QPoint DragStartPos;          // 开始拖拽的位置
    QPoint DragCurrentPos;        // 当前拖拽位置
    QPoint TabGrabOffset;         // 鼠标在标签内的抓取偏移
    bool DragAccepted;            // 拖拽是否被接受
    
    // === 卡牌交换状态 ===
    int CurrentIndex;             // 当前标签在数组中的索引
    int LastSwapCheckX;           // 上次检查交换时的X位置
    bool HasSwappedInCurrentDrag; // 当前拖拽中是否已经发生过交换
    
    // === 位置管理 ===
    QPoint OriginalPosition;      // 原始位置
    QPoint FloatingPosition;      // 浮动位置（脱离布局）
    int PreviewDropIndex;         // 预览放置索引
    
    // === 拖出预览窗口 ===
    QWidget* PreviewWindow;       // 预览窗口
    QWidget* PreviewContent;      // 预览窗口内容
    QPoint PreviewWindowOffset;   // 预览窗口相对鼠标的偏移
    QRect TabButtonRectInSnapshot; // 标签按钮在快照中的位置（用于鼠标位置计算）
    
    // === 线性动画系统 ===
    QTimer* AnimationTimer;       // 动画定时器
    QPoint AnimationStartPos;     // 动画起始位置
    QPoint AnimationEndPos;       // 动画结束位置
    qint64 AnimationStartTime;    // 动画开始时间
    int AnimationDuration;        // 动画持续时间(ms)
    bool IsAnimating;             // 是否正在动画
    
    // === 常量配置 ===
    static const int DRAG_THRESHOLD = 8;           // 开始拖拽的像素阈值
    static const int PULLOUT_THRESHOLD = 30;       // 拖出的像素阈值
    static const int CLOSE_BUTTON_SIZE = 16;       // 关闭按钮大小
    static const int ANIMATION_FPS = 60;           // 动画帧率
    static const QSize PREVIEW_WINDOW_SIZE;        // 预览窗口大小 (640x480)
    static const float PREVIEW_OPACITY;            // 预览窗口透明度 (0.5)
};

